import mqtt from 'mqtt'

/**
 * mqtt工具
 */
export class MqttUtils {
    constructor(url, uname, passwd) {
        this.triggers = []
        this.options = {
            clean: true,
            connectTimeout: 4000,
            reconnectPeriod: 4000, // ms
            clientId: 'xymqtt_' + Math.random()
                .toString(16)
                .substring(2, 8),
            username: uname,
            password: passwd,
        }
        // 连接客户端
        this.client = mqtt.connect(url, this.options)
        let _t = this
        if (this.client.on) {
            // 连接回调
            this.client.on('connect', function () {
                console.log('mqtt connect success')
            })
            // 重连回调
            this.client.on('reconnect', () => {
                _t.retryTimes += 1
                if (_t.retryTimes > _t.maxRetryTimes) {
                    try {
                        _t.client.end()
                    } catch (error) {
                        console.error(error)
                    }
                }
            })
            // 连接错误回调
            this.client.on('error', error => {
                console.log('Connection failed', error)
            })
            // 消息回调
            this.client.on('message', function (topic, message) {
                let _msg = message
                if (topic && typeof message === 'string') {
                    _msg = JSON.parse(message)
                }
                _t.triggers.forEach(item => {
                    console.log(item, topic)
                    if (item.topic === topic) {
                        let _trigger = eval('(' + item.trigger + ')')
                        if (typeof _trigger === 'function' && _trigger(_msg)) {
                            _t.publish(item.cbtopic, item.value, message)
                        }
                    }
                })
            })
        }
    }

    subscribe(topic, value, trigger, cbtopic) {
        this.client.subscribe(topic, function (err) {
            if (err) {
                console.error("subscribe " + topic + "error: " + err)
            }
        })
        this.triggers.push({
            topic: topic,
            value: value,
            trigger: trigger,
            cbtopic: cbtopic,
        })
    }

    close() {
        if (this.client.connected) {
            try {
                this.client.end()
                console.log('Disconnected')
            } catch (error) {
                console.log('Disconnect failed', error.toString())
            }
        }
    }

    publish(topic, payload, message) {
        try {
            let _payloadFunc = eval('(' + payload + ')')
            let _payload = _payloadFunc(message)
            this.client.publish(topic, _payload, error => {
                if (error) {
                    console.log('Publish error', error)
                }
            })
        } catch (err) {
            console.log('Publish error', err)
        }
    }
}